import sys
import subprocess
from tool import util
import cv2
import os
import _thread

from PySide2.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox, QTextBrowser, QFileDialog, QSizePolicy, QFrame, QProgressBar, QSlider, QSplitter, QAction, QComboBox
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import Qt, QDir, QTimer, QRect
from PySide2.QtGui import QPixmap, QImage, QIcon

from RangeSlider import QRangeSlider
from DragDropView import DragDropView
from VideoPlayer import VideoPlayer
from VideoPlayer import *

from tool import util, storage

markViewGeometryKey = "markViewGeometry"
dirPathKey = "dirPath"


class Watermark(QMainWindow):
    def __init__(self):
        super().__init__()

        self.defaultConfig()

        self.setUI()
        
        self.slder_video_pressed = False  # 判断当前进度条识别否被鼠标点击
        self.filename = None
        # 0-去水印 1-剪裁
        self.mode = 0  

    def defaultConfig(self):
        geometry = storage.getValue(markViewGeometryKey)
        if not geometry:
            geometry = {"x": 20, "y": 20, "w": 100, "h": 50}
        self.markGeometry = QRect(geometry["x"], geometry["y"], geometry["w"], geometry["h"])

        path = storage.getValue(dirPathKey)
        if not path:
            path = os.path.expanduser('~')
        self.dirPath = path

    def setUI(self):

        self.statusBar()

        self.toolbar = self.addToolBar("Tool Bar")

        combo = QComboBox(self)
        combo.addItem("去水印模式")
        combo.addItem("裁剪模式")
        combo.activated[str].connect(self.onActivatedMode)
        self.toolbar.addWidget(combo)

        vbox = QVBoxLayout()
        main_frame = QWidget()
        main_frame.setLayout(vbox)
        # self.setLayout(vbox)
        self.setCentralWidget(main_frame)
        
        self.title = QLabel("标题")
        self.fileButton = QPushButton("选择视频")
        self.fileButton.clicked.connect(self.onClickFile)

        hboxTitle = QHBoxLayout()
        hboxTitle.addWidget(self.title)
        hboxTitle.addWidget(self.fileButton)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)

        self.player = VideoPlayer()
        self.player.setStyleSheet('background-color: rgb(10, 10, 10); ')
        self.player.progressChanged.connect(self.playerProgressChanged)
        self.player.stateChanged.connect(self.playerStateChanged)
        self.player.setSizePolicy(sizePolicy)
        
        vbox.addLayout(hboxTitle)
        vbox.addWidget(self.player)

        self.hboxBar = QHBoxLayout()
        vbox.addLayout(self.hboxBar)

        self.playButton = QPushButton("播放")
        self.playButton.clicked.connect(self.onClickPlay)

        self.currentLabel = QLabel("00:00")
        self.totalLable = QLabel("00:00")

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setMinimum(0)
        self.slider.setTracking(False)
        self.slider.sliderReleased.connect(self.releaseSlider)
        self.slider.sliderPressed.connect(self.pressSlider)
        self.slider.sliderMoved.connect(self.moveSlider)

        self.rangeSlider = QRangeSlider()
        self.rangeSlider.setMin(0)
        self.rangeSlider.setRange(0, 10)
        self.rangeSlider.setVisible(False)
        self.rangeSlider.startValueChanged.connect(self.startValueChanged)

        self.hboxBar.addWidget(self.playButton)
        self.hboxBar.addWidget(self.currentLabel)
        self.hboxBar.addWidget(self.slider)
        self.hboxBar.addWidget(self.rangeSlider)
        self.hboxBar.addWidget(self.totalLable)

        hbox = QHBoxLayout()
        # hbox.addStretch(1)
        vbox.addLayout(hbox)

        self.ffmpegButton = QPushButton("去水印")
        self.ffmpegButton.clicked.connect(self.onClickFfmpeg)

        hbox.addWidget(self.ffmpegButton)

        self.maskView = DragDropView(self.player)
        self.maskView.setStyleSheet(
            'background-color: rgb(200, 10, 70, 0.4); ')
        self.maskView.setVisible(False)

    def startValueChanged(self, number):
        self.player.position(number)

    def onActivatedMode(self):
        if self.mode == 0:
            # 裁剪
            self.mode = 1
            self.rangeSlider.setVisible(True)
            self.slider.setVisible(False)
            self.ffmpegButton.setText("开始裁剪")
            self.maskView.setVisible(False)
        else:
            self.mode = 0
            self.rangeSlider.setVisible(False)
            self.slider.setVisible(True)
            self.ffmpegButton.setText("去水印")
            self.maskView.setVisible(True)
        
        self.player.setVideo(self.filename)

    def onClickPlay(self):
        if self.player.playing:
            self.player.stop()
        else:
            self.player.play()

    def onClickFile(self):
        self.filename, _ = QFileDialog.getOpenFileName(
            self,  "选取文件", self.dirPath)
        if not self.filename:
            return
        
        self.dirPath = util.getDir(self.filename)
        storage.store(dirPathKey, self.dirPath)

        self.title.setText("文件名：{}".format(self.filename))
        self.statusBar().showMessage('加载视频中...')

        self.player.setVideo(self.filename)

        if self.mode == 1:
            # 裁剪
            self.maskView.setVisible(False)
        else:
            # 去水印
            self.maskView.setVisible(True)

            if self.markGeometry.x() > self.size().width():
                self.markGeometry = QRect(20, self.markGeometry.y(), self.markGeometry.width(), self.markGeometry.height())
            if self.markGeometry.y() > self.size().height():
                self.markGeometry = QRect(self.markGeometry.x(), 20, self.markGeometry.width(), self.markGeometry.height())

            self.maskView.setGeometry(self.markGeometry)


    def playerProgressChanged(self, progress):
        self.currentLabel.setText(self.player.format_time(progress))
        self.slider.setValue(progress)

    def playerStateChanged(self, state):
        if state == Success:
            self.statusBar().showMessage('加载视频成功')
            total_second = self.player.total_second
            self.totalLable.setText(self.player.format_time(total_second))
            if self.mode == 1:
                self.rangeSlider.setMax(total_second)
                self.rangeSlider.setRange(0, total_second)
            else:
                self.slider.setMaximum(total_second)

        elif state == Failure:
            self.statusBar().showMessage('加载视频失败')
        elif state == Play:
            self.playButton.setText("暂停")
        elif state == Stop:
            self.playButton.setText("播放")
        elif state == Pause:
            self.playButton.setText("播放")
        elif state == Start:
            self.playButton.setText("暂停")


    def releaseSlider(self):
        if self.slder_video_pressed:
            self.player.play()

        self.slder_video_pressed = False

    def pressSlider(self):
        if self.player.playing:
            self.slder_video_pressed = True
        self.player.stop()
        self.player.position(self.slider.value())

    def moveSlider(self, position):
        self.player.position(position)


    def onClickFfmpeg(self):
        if not self.filename:
            return

        self.player.stop()

        if self.mode == 1:
            _thread.start_new_thread(self.onCut, ("Thread-cut-1", 0))
        else:
            _thread.start_new_thread(self.onFfmpeg, ("Thread-ff-1", 0))
    
    def onFfmpeg(self, threadName, delay):
        self.ffmpegButton.setEnabled(False)
        self.ffmpegButton.setText("去水印中，请稍后...")

        list = os.path.splitext(self.filename)
        outfile = list[0] + "_wm" + list[1]

        self.markGeometry = self.maskView.geometry()
        x = str(self.markGeometry.x())
        y = str(self.markGeometry.y())
        w = str(self.markGeometry.width())
        h = str(self.markGeometry.height())
        storage.store(markViewGeometryKey, {"x": self.markGeometry.x(), "y": self.markGeometry.y(), "w": self.markGeometry.width(), "h": self.markGeometry.height()})

        infile = self.filename

        command = 'ffmpeg -y -i ' + infile+' -vf delogo=x=' + x + ':y=' + y + ':w=' + w + ':h=' + h + ' ' + outfile
        util.terminal(command)

        self.ffmpegButton.setEnabled(True)
        self.ffmpegButton.setText("去水印")

        title = self.title.text() + "（完成）"
        self.title.setText(title)

        self.filename = outfile
        self.title.setText(self.filename)

        self.player.setVideo(self.filename)

        self.statusBar().showMessage('去水印完成')
        _thread.exit()

    def onCut(self, threadName, delay):
        self.ffmpegButton.setEnabled(False)
        self.ffmpegButton.setText("裁剪中，请稍后...")

        list = os.path.splitext(self.filename)
        outfile = list[0] + "_cut" + list[1]

        infile = self.filename

        start = str(self.rangeSlider.start())
        end = str(self.rangeSlider.end())

        command = 'ffmpeg -ss ' + start + ' -to ' + end + ' -i ' + infile +' -acodec copy -vcodec copy ' + outfile + ' -y'
        util.terminal(command)

        self.ffmpegButton.setEnabled(True)
        self.ffmpegButton.setText("开始裁剪")

        self.statusBar().showMessage('裁剪完成')
        _thread.exit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    view = Watermark()
    desktop = QApplication.desktop()
    view.resize(desktop.width()*0.7, desktop.height()*0.7)
    view.move(100, 0)
    view.setWindowTitle('视频编辑工具')
    view.show()
    sys.exit(app.exec_())
